<?php
/**
 * Created by PhpStorm.
 * User: DongYao
 * Date: 2017/12/12
 * Time: 下午5:43
 */

namespace XmtApp\Modules\Admin\Controllers\Api;


use App\Http\Resources\UserResource;
use App\Http\Resources\UsersResource;
use App\Jobs\BackendBatchGiveUserScore;
use App\Jobs\GiveUserScoreNotice;
use App\Rules\PriceRule;
use App\Support\Facades\ChargeOrder;
use App\Support\Facades\OperationLog;
use App\Tables\User;
use Illuminate\Database\QueryException;
use Illuminate\Http\Request;
use App\Http\Requests\UserPost;
use Validator;
use App\Exceptions\OperationException;
use App\Tables\UserScoreTransferRecord;
use DB;
use Log;

class UserController extends BaseController
{
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 查询注册用户列表
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function index(Request $request)
    {
        $query = new User();

        // 日期查询
        if ($request->filled('created_at')) {
            $query = $query->whereBetween('created_at', $request->created_at);
        }

        // 关键字查询
        if ($request->filled('keyword')) {
            $query = $query->where(function ($query) use ($request) {
                $query->orWhere('name', 'like', "%{$request->keyword}%");
                $query->orWhere('realname', 'like', "%{$request->keyword}%");
                $query->orWhere('nickname', 'like', "%{$request->keyword}%");
                $query->orWhere('mobile', 'like', "%{$request->keyword}%");
            });
        }

        if ($request->filled('province_code')) {
            $query = $query->where('province_code', $request->province_code);
        }

        if ($request->filled('city_code')) {
            $query = $query->where('city_code', $request->city_code);
        }

        if ($request->filled('district_code')) {
            $query = $query->where('district_code', $request->district_code);
        }

        $query = $query->orderBy('created_at', 'desc');

        $data = $query->general()->paginate($request->header('pageSize'));

        return new UsersResource($data);
    }

    /**
     * 添加注册用户
     * @param UserPost $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function add(UserPost $request)
    {
        $data = $request->all(['name', 'password', 'sex', 'is_effect', 'source', 'email', 'nickname', 'realname', 'mobile']);

        $user = new User($data);
        $user->password = bcrypt($data['password']);
        $user->type = 0;
        $res = $user->save();

        if ($res) {
            return response()->json(ajax_return(true, '添加成功', new UserResource($user)));
        } else {
            return response()->json(ajax_return(false, '添加失败', []));
        }
    }

    /**
     * 修改注册用户信息
     * @param $id
     * @param UserPost|Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function update($id, UserPost $request)
    {
        $data = $request->all(['email', 'nickname', 'realname', 'mobile']);

        $table = new User();

        $res = $table->where('id', $id)->update($data);

        if ($res) {
            return response()->json(ajax_return(true, '修改成功', []));
        } else {
            return response()->json(ajax_return(false, '修改失败', []));
        }
    }

    /**
     * 批量赠送积分给用户
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function batchGiveScore(Request $request)
    {
        /** 至少必须有一个查询参数约束 */
        if (!$request->filled('province_code')) {
            return response()->json(ajax_return(false, '必须选择需要赠送用户的省份', []));
        }

        if (!$request->filled('score') || $request->score < 1 || $request->score > 2000) {
            return response()->json(ajax_return(false, '赠送的积分数量必须在1~2000个之间', []));
        }

        dispatch(new BackendBatchGiveUserScore($request->score, $this->user->id, $request->province_code, $request->city_code, $request->district_code));

        return response()->json(ajax_return(true, "批量赠送给用户积分任务已经添加至后台任务", []));
    }

    /**
     * 批量赠送积分给用户
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function giveScore(Request $request)
    {
        if (!$request->filled('score') || $request->score < 1 || $request->score > 2000) {
            return response()->json(ajax_return(false, '赠送的积分数量必须在1~2000个之间', []));
        }

        if (!$request->filled('user_id')) {
            return  response()->json(ajax_return(false, '用户不存在'));
        }

        DB::beginTransaction();
        try {
            $user = User::where('id', $request->user_id)->lockForUpdate()->first();
            if (empty($user)) {
                throw new OperationException('后台赠送用户积分失败-用户不存在', [$request->user_id, $request->score]);
            }

            $user->score = bcadd($user->score, $request->score, 0);
            $res = $user->save();
            if (!$res) {
                throw new OperationException('后台赠送用户积分失败-更新用户积分失败', [$user->id, $user->name, $request->score]);
            }

            /**
             * 增加充值赠送积分数量记录
             */
            $user_score_record = new UserScoreTransferRecord();
            $user_score_record->user_id = $user->id;
            $user_score_record->order_sn =  'BG' . $user->id . date('YmdHis');;
            $user_score_record->type = 'backend_give';
            $user_score_record->score = $request->score;
            $user_score_record->total_score = $user->score;
            $res = $user_score_record->save();
            if ($res === false) {
                throw new OperationException('后台赠送用户积分失败-增加充值赠送积分记录失败', [$user->id, $user->name, $request->score]);
            }
            DB::commit();

            // 记录操作日志
            $log_message = "管理员【{$this->user->name}】手动给用户【{$user->name}】积分账户增加了{$request->score}个积分";
            OperationLog::info('后台赠送积分', $log_message);

            // 积分赠送成功后给用户发送通知
            dispatch(new GiveUserScoreNotice($request->score, $user));

            return response()->json(ajax_return(true, '积分赠送成功'));
        } catch (OperationException $exception) {
            DB::rollBack();
        } catch (QueryException $exception) {
            DB::rollBack();
        } catch (Throwable $exception) {
            DB::rollBack();
        }

        return  response()->json(ajax_return(false, '积分赠送失败'));
    }

    /**
     * 设置注册账户是否有效
     * @param $id
     * @param $status
     * @return \Illuminate\Http\JsonResponse
     * @internal param UserPost $request
     */
    public function toggleStatus($id, $status)
    {
        $table = new User();

        $res = $table->where('id', $id)->update(['is_effect' => $status]);

        if ($res) {
            return response()->json(ajax_return(true, '设置成功'));
        } else {
            return response()->json(ajax_return(false, '设置失败'));
        }
    }

    /**
     * 后台给用户充值
     * @param $id
     * @param $money
     * @return \Illuminate\Http\JsonResponse
     */
    public function backendCharge($id, $money)
    {
        Validator::make(['id' => $id, 'money' => $money], [
            'id' => 'exists:users,id',
            'money' => ['required', new PriceRule(), 'max:200', 'min:1']
        ])->validate();

        $res = ChargeOrder::backendCharge($id, $money, $this->user->name);
        if ($res === true) {
            return response()->json(ajax_return(true, '充值成功'));
        }

        return response()->json(ajax_return(false, '充值失败'));
    }
}